//
//  WCBuildMessage.m
//  WabbitCode
//
//  Created by William Towe on 2/8/09.
//  Copyright 2009 Revolution Software. All rights reserved.
//

#import "WCBuildMessage.h"
#import "WCTextFile.h"
#import "WCErrorsAndWarningsGroup.h"
#import "NSImage+WCExtensions.h"
#import "WCFileError.h"
#import "WCFileWarning.h"


@implementation WCBuildMessage
#pragma mark *** Subclass Overrides ***
- (void)dealloc {
	[_messageText release];
	[super dealloc];
}

- (NSString *)description {
	return [NSString stringWithFormat:@"File: %@\nLine: %u", [[self textFile] name], [self lineNumber]];
}

- (BOOL)canRenameNode {
	return NO;
}

- (BOOL)canDeleteNode {
	return NO;
}

- (NSString *)name {
	switch ([self messageType]) {
		case WCBMTypeError:
		case WCBMTypeWarning:
			return [NSString stringWithFormat:@"%@", [self messageText]];
		case WCBMTypeFile:
			return [[self textFile] name];
		case WCBMTypeFileExpanded:
			return [NSString stringWithFormat:@"%@ - %@",[[self textFile] name], [[self textFile] absoluteFilePath]];
		case WCBMTypeBuild:
		case WCBMTypeBuildSuccess:
		case WCBMTypeSuccessWarnings:
		case WCBMTypeFailureErrors:
			return [self messageText];
		default:
			return nil;
	}
}

- (BOOL)isLeaf {
	if ([self messageType] == WCBMTypeError || [self messageType] == WCBMTypeWarning || [self messageType] == WCBMTypeFailureErrors || [self messageType] == WCBMTypeSuccessWarnings || [self messageType] == WCBMTypeBuildSuccess)
		return YES;
	return NO;
}

- (id)copyWithZone:(NSZone *)zone {
	WCBuildMessage *copy = [super copyWithZone:zone];
	
	copy->_messageText = [_messageText copy];
	copy->_messageType = _messageType;
	copy->_textFile = _textFile;
	copy->_lineNumber = _lineNumber;
	
	return copy;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
	WCBuildMessage *copy = [super mutableCopyWithZone:zone];
	
	copy->_messageText = [_messageText copy];
	copy->_messageType = _messageType;
	copy->_textFile = _textFile;
	copy->_lineNumber = _lineNumber;
	
	return copy;
}
#pragma mark *** Public Methods ***
#pragma mark Accessors
@synthesize messageText=_messageText, messageType=_messageType, textFile=_textFile, lineNumber=_lineNumber;

@dynamic usesCustomAttributes;
- (BOOL)usesCustomAttributes {
	switch ([self messageType]) {
		case WCBMTypeFile:
		case WCBMTypeBuild:
		case WCBMTypeFailureErrors:	
		case WCBMTypeError:
			return YES;
		case WCBMTypeWarning:
		case WCBMTypeBuildSuccess:
		case WCBMTypeSuccessWarnings:
		default:
			return NO;
	}
}

@dynamic icon;
- (NSImage *)icon {
	switch ([self messageType]) {
		case WCBMTypeError:
			return [NSImage imageNamed:@"Error14x14"];
		case WCBMTypeWarning:
			return [NSImage imageNamed:@"Warning14x14"];
		case WCBMTypeBuildSuccess:
			return [NSImage imageNamed:@"Success16x16"];
		case WCBMTypeFile:
		case WCBMTypeFileExpanded: {
			NSUInteger errors = [self numberOfErrors], warnings = [self numberOfWarnings];
			
			if (errors && warnings) {
				NSImage *retval = [[[NSImage alloc] initWithSize:NSMakeSize(16.0, 16.0)] autorelease];
				NSImage *fileIcon = [[self textFile] fileIcon];
				[fileIcon setSize:[retval size]];
				
				[retval lockFocus];
				[fileIcon compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
				[[NSImage imageNamed:@"Error8x8"] compositeToPoint:NSMakePoint(8.0, 8.0) operation:NSCompositeSourceOver];
				[[NSImage imageNamed:@"Warning8x8"] compositeToPoint:NSMakePoint(8.0, 0.0) operation:NSCompositeSourceOver];
				[retval unlockFocus];
				
				return retval;
			}
			else if (errors) {
				return [[[self textFile] fileIcon] badgedImageWithImage:[NSImage imageNamed:@"Error8x8"] originalSize:NSMakeSize(16.0, 16.0) badgeSize:NSMakeSize(8.0, 8.0)];
			}
			else if (warnings) {
				return [[[self textFile] fileIcon] badgedImageWithImage:[NSImage imageNamed:@"Warning8x8"] originalSize:NSMakeSize(16.0, 16.0) badgeSize:NSMakeSize(8.0, 8.0)];
			}
		}
			return [[self textFile] fileIcon];
		case WCBMTypeBuild:
			return [NSImage imageNamed:@"Build16x16"];
		case WCBMTypeFailureErrors:
			return [NSImage imageNamed:@"Error14x14"];
		case WCBMTypeSuccessWarnings:
			return [NSImage imageNamed:@"Warning14x14"];
	}
	return nil;
}

- (NSString *)messageLocation; {
	return [NSString stringWithFormat:@"%@:%u", [[self textFile] name], [self lineNumber]+1];
}

- (NSString *)fileName {
	return [[self textFile] name];
}

- (NSString *)errorOrWarning {
	if ([self messageType] == WCBMTypeError)
		return @"error";
	return @"warning";
}

@dynamic numberOfErrors;
- (NSUInteger)numberOfErrors {
	NSUInteger count = 0;
	for (WCBuildMessage *bm in [self childNodes]) {
		if ([bm messageType] == WCBMTypeError)
			count++;
	}
	return count;
}

@dynamic numberOfWarnings;
- (NSUInteger)numberOfWarnings {
	NSUInteger count = 0;
	for (WCBuildMessage *bm in [self childNodes]) {
		if ([bm messageType] == WCBMTypeWarning)
			count++;
	}
	return count;
}

@dynamic lineNumberAsObject;
- (NSNumber *)lineNumberAsObject {
	return [NSNumber numberWithUnsignedInteger:_lineNumber];
}

@dynamic numberOfErrorsAndWarnings;
- (NSUInteger)numberOfErrorsAndWarnings {
	return [self numberOfErrors] + [self numberOfWarnings];
}

- (id)initWithCoder:(NSCoder *)coder {
	if (!(self = [super initWithCoder:coder]))
		return nil;
	
	_messageType = [coder decodeIntegerForKey:@"messageType"];
	_messageText = [[coder decodeObjectForKey:@"messageText"] retain];
	_textFile = [coder decodeObjectForKey:@"textFile"];
	_lineNumber = [coder decodeIntegerForKey:@"lineNumber"];
	
	return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
	[super encodeWithCoder:coder];
	[coder encodeInteger:_messageType forKey:@"messageType"];
	[coder encodeObject:_messageText forKey:@"messageText"];
	[coder encodeConditionalObject:_textFile forKey:@"textFile"];
	[coder encodeInteger:_lineNumber forKey:@"lineNumber"];
}
#pragma mark Creation
+ (id)buildMessageWithType:(WCBMType)type text:(NSString *)text textFile:(WCTextFile *)textFile lineNumber:(NSUInteger)lineNumber; {
	return [[[[self class] alloc] initWithType:type text:text textFile:textFile lineNumber:lineNumber] autorelease];
}

- (id)initWithType:(WCBMType)type text:(NSString *)text textFile:(WCTextFile *)textFile lineNumber:(NSUInteger)lineNumber; {
	if (!(self = [super init]))
		return nil;
	
	_messageType = type;
	_messageText = [text retain];
	_textFile = textFile;
	_lineNumber = (lineNumber == 0)?lineNumber:--lineNumber;
	
	if (type == WCBMTypeError)
		[_textFile addFileError:[WCFileError fileErrorWithBuildMessage:self] atLineNumber:_lineNumber];
	else if (type == WCBMTypeWarning)
		[_textFile addFileWarning:[WCFileWarning fileWarningWithBuildMessage:self] atLineNumber:_lineNumber];
	
	return self;
}
@end
